package com.wifi.IBackService;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Arrays;

import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.widget.Toast;

import com.wifi.utils.Utils;
import com.wifi.utils.WifiUtils;

import rx.Observable;
import rx.Scheduler;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.observers.Observers;
import rx.schedulers.Schedulers;

/**
 * Created by Administrator on 2016/10/7.
 */
public class ThreadService extends Service {

        private static final String TAG = "BackService";
        private static final long HEART_BEAT_RATE = 15 * 1000;//15秒

        public static  String HOST = "192.168.77.1";// "192.168.1.21";//
        public static  int PORT = 8888;

        public static final String MESSAGE_ACTION="org.feng.message_ACTION";
        public static final String HEART_BEAT_ACTION="org.feng.heart_beat_ACTION";
        public static final String WIFI_REBOOT="org.feng.wifi_reboot";

        private ReadThread mReadThread;
        private LocalBroadcastManager mLocalBroadcastManager;
        private WeakReference<Socket> mSocket;

        // For heart Beat
        private Handler mHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what){
                    case 1:
                        Observable.create(new Observable.OnSubscribe<String>() {
                            @Override
                            public void call(Subscriber<? super String> subscriber) {
                                if (!isSuccess) {//重新连接
                                    //获取当前所连wifi
                                    WifiInfo wifiInfo = wm.getConnectionInfo();
                                    connectedSSID = wifiInfo.getSSID();
                                    connectedSSID=connectedSSID.replace("\"","");
                                    sp= getSharedPreferences("wifiSetting", Activity.MODE_PRIVATE);
                                    String ssid = sp.getString("ssid", "sn1111111");//是否为上一次连接的wifi
                                    if(connectedSSID.indexOf(ssid)!=-1){//连接正确wifi
                                        //socket重新连接,上一轮soctet相关对象置空
                                        mHandler.removeCallbacks(heartBeatRunnable);
                                        mReadThread.release();
                                        releaseLastSocket(mSocket);
                                        new InitSocketThread().start();
                                    }else {
                                        //否则重启wifi
                                        Intent intent=new Intent(WIFI_REBOOT);
                                        intent.putExtra("wifiReboot", "wifiReboot");
                                        mLocalBroadcastManager.sendBroadcast(intent);
                                    }
                                }
                                subscriber.onNext("消息发送"+isSuccess);
                            }
                        }).subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
                                .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
                                .subscribe(new Action1<String>() {
                                    @Override
                                    public void call(String s) {
                                        if(s!=null){
                                            Log.d("rx","检验-----"+s);
                                        }
                                    }
                                });
                        break;
                }
                super.handleMessage(msg);
            }
        };
        String connectedSSID;
        private Runnable heartBeatRunnable = new Runnable() {
            @Override
            public void run() {
                if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
                    sendMsg("$heartbeat;");//就发送一个\r\n过去 如果发送失败，就重新初始化一个socket
                }
                mHandler.postDelayed(this, HEART_BEAT_RATE);
            }
        };

        private long sendTime = 0L;

        private IBackService.Stub iBackService = new IBackService.Stub() {

            @Override
            public boolean sendMessage(String message) throws RemoteException {
                return sendMsg(message);
            }

            @Override
            public boolean sendFile(String path) throws RemoteException {
                return SendFile(path);
            }

            @Override
            public void getNetSocket() throws RemoteException {
                mHandler.removeCallbacks(heartBeatRunnable);
                releaseLastSocket(mSocket);
                new InitSocketThread().start();
            }
        };

        @Override
        public IBinder onBind(Intent arg0) {
            return iBackService;
        }

        WifiManager wm;
        SharedPreferences sp;
        @Override
        public void onCreate() {
            super.onCreate();
            wm = (WifiManager) getSystemService(WIFI_SERVICE);

            //socket初始化
            new InitSocketThread().start();
            mLocalBroadcastManager=LocalBroadcastManager.getInstance(this);
        }

        public boolean SendFile(String path){
            try {
                Socket soc = mSocket.get();
                OutputStream outputData = soc.getOutputStream();
                FileInputStream fileInput = new FileInputStream(path);
                int size = -1;
                byte[] buffer = new byte[1024];
                while((size = fileInput.read(buffer, 0, 1024)) != -1){
                    outputData.write(buffer, 0, size);
                }
                return true;
            } catch (Exception e) {
                return false;
            }
        }

        String sendMsg;
        boolean isSuccess=true;
        public boolean sendMsg(final String msg) {
            sendMsg=msg;
            if(msg!=""){
                if (null == mSocket || null == mSocket.get()) {
                    //socket已断开置空，发送失败
                    isSuccess=false;
                    Message obtain = Message.obtain();
                    obtain.what=1;
                    mHandler.sendMessage(obtain);
                    return false;
                }
                Socket soc = mSocket.get();
                try {
                        if (!soc.isClosed() && !soc.isOutputShutdown()) {
                            Observable.create(new Observable.OnSubscribe<String>() {
                                @Override
                                public void call(Subscriber<? super String> subscriber) {
                                    String message = sendMsg + "\r\n";
                                    try {
                                        Socket soc = mSocket.get();
                                        OutputStream os = null;
                                        os = soc.getOutputStream();
                                        os.write(message.getBytes());
                                        os.flush();
                                        isSuccess=true;
                                        sendTime = System.currentTimeMillis();//每次发送成数据，就改一下最后成功发送的时间，节省心跳间隔时间
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                        isSuccess=false;
                                    }finally {
                                        subscriber.onNext(message);
                                        subscriber.onCompleted();
                                    }
                                }
                            }).subscribeOn(Schedulers.io()) // 指定 subscribe() 发生在 IO 线程
                              .observeOn(AndroidSchedulers.mainThread()) // 指定 Subscriber 的回调发生在主线程
                              .subscribe(new Action1<String>() {
                                  @Override
                                  public void call(String s) {
                                      Log.d("rx","------发送："+s+"----"+isSuccess);
                                  }
                              });
                        } else {
                            isSuccess=false;
                            return false;
                        }
                } catch (Exception e) {
                    e.printStackTrace();
                    isSuccess=false;
                    return false;
                }finally {
                    Message obtain = Message.obtain();
                    obtain.what=1;
                    mHandler.sendMessage(obtain);
                }
            }
            return true;
        }


        private void initSocket() {
            //获取网关地址
            DhcpInfo di = wm.getDhcpInfo();
            long getewayIpL = di.gateway;
            String getwayIpS = Utils.long2ip(getewayIpL);
            this.HOST=getwayIpS;

            //socket弱引用初始化
            try {
                Socket so = new Socket(HOST, PORT);
                mSocket = new WeakReference<Socket>(so);
                mReadThread = new ReadThread(so);
                mReadThread.start();
                mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//初始化成功后，就准备发送心跳包
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //初始化Socket
        class InitSocketThread extends Thread {
            @Override
            public void run() {
                super.run();
                initSocket();
            }
        }

        // Thread to read content from Socket
        class ReadThread extends Thread {
            private WeakReference<Socket> mWeakSocket;
            private boolean isStart = true;//当前线程中的socket断开连接时，isStart用来终止线程read操作

            public ReadThread(Socket socket) {
                mWeakSocket = new WeakReference<Socket>(socket);//弱引用，当socket置空时 Socket对象立马会被回收
                sendMsg("$first_connect;");
            }

            public void release() {
                isStart = false;
                releaseLastSocket(mWeakSocket);
            }

            @Override
            public void run() {//socket消息读取
                super.run();
                Socket socket = mWeakSocket.get();
                if (null != socket) {
                    try {
                        InputStream is = socket.getInputStream();
                        byte[] buffer = new byte[1024 * 4];
                        int length = 0;
                        while (!socket.isClosed() && !socket.isInputShutdown()
                                && isStart && ((length = is.read(buffer)) != -1)) {
                            if (length > 0) {
                                String message = new String(Arrays.copyOf(buffer,
                                        length)).trim();
                                Log.e(TAG, message);
                                //收到服务器过来的消息，就通过Broadcast发送出去
                                if(message.equals("heartbeat")){//处理心跳回复
                                    Intent intent=new Intent(HEART_BEAT_ACTION);
                                    mLocalBroadcastManager.sendBroadcast(intent);
                                }else  if(message.indexOf("wrong_cmd")!=-1){//心跳包响应

                                }else{
                                    //其他消息回复
                                    Intent intent=new Intent(MESSAGE_ACTION);
                                    intent.putExtra("message", message);
                                    mLocalBroadcastManager.sendBroadcast(intent);
                                }
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

    //优化socekt置空
    private void releaseLastSocket(WeakReference<Socket> mSocket) {
        try {
            if (null != mSocket) {
                Socket sk = mSocket.get();
                if(sk!=null){
                    if (!sk.isClosed()) {
                        sk.close();
                    }
                    sk = null;//弱引用置空
                    mSocket = null;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
